#include "pch.h"
#include "SceneNode.h"

SceneNode::SceneNode()
{
	this->children = new List();

	this->localTrandormation = identity();
	this->worldTransformation = identity();
}

void SceneNode::Add(SceneNode* node)
{
	this->children->Add(node);
}

// Removes an existing child node.
void SceneNode::Remove(SceneNode* node)
{
	this->children->Remove(node);
}

SceneNode* SceneNode::GetChild(int n)
{
	return (SceneNode*)this->children->GetItem(n);
}

// Returns the number of child nodes
int SceneNode::Count()
{
	return this->children->Count();
}

// Recursively resolves the world transformation for all items in a given scene graph.
void SceneNode::ResolveChildrenWorldTransform()
{
	int count = this->children->Count();

	for(int i = 0; i < count; i ++)
	{
		SceneNode* child = (SceneNode*)this->children->GetItem(i);

		child->worldTransformation = mul(this->worldTransformation, child->localTrandormation);
	}
}

// Resolves all the Model transformations for this node and it's children.
void SceneNode::ResolveModelTransformation(BasicCamera* camera, List* listOfRenderableNodes)
{
	int count = this->children->Count();

	for(int i = 0; i < count; i ++)
	{
		SceneNode* child = (SceneNode*)this->children->GetItem(i);

		child->worldTransformation = mul(this->worldTransformation, child->localTrandormation);

		// test if the Scene Graph node is renderable and visible from the camera, 
		// if it is add the scene graph node to the list of renderable nodes.
		if (child->IsRenderable())
		{
			if (child->IsVisibleFromCamera(camera))
			{
				listOfRenderableNodes->Add(child);
			}
		}

		child->ResolveModelTransformation(camera, listOfRenderableNodes);
	}
}

// Using the frustrum volume from the camera, tests if the geometry is visiblw, if it is visible then returns
// true.
bool SceneNode::IsVisibleFromCamera(BasicCamera *camera)
{
	return true;
}

void SceneNode::Render(
		ID3D11DeviceContext1* Direct3DContext, 
		ModelViewProjectionConstantBuffer ModelViewProjectionBuffer,
		ID3D11Buffer* constantBuffer,
		ID3D11SamplerState* textureSampler,

		ShapeLibrary *shapeLibrary,
		TextureLibrary* textureLibrary,
		ShaderPairLibrary* shaderPairLibrary,
		ModelLibrary* modelLibrary)
{

}

void SceneNode::RendSceneNodes(
		ID3D11DeviceContext1* Direct3DContext, 
		ModelViewProjectionConstantBuffer ModelViewProjectionBuffer,
		ID3D11Buffer* constantBuffer,
		ID3D11SamplerState* textureSampler,

		ShapeLibrary *shapeLibrary,
		TextureLibrary* textureLibrary,
		ShaderPairLibrary* shaderPairLibrary,
		ModelLibrary* modelLibrary,

	List* listOfRenderableNodes)
{
	int count = listOfRenderableNodes->Count();

	for (int i = 0; i < count; i++)
	{
		((SceneNode*)listOfRenderableNodes->GetItem(i))->Render(
			Direct3DContext,
			ModelViewProjectionBuffer,
			constantBuffer,
			textureSampler,

			shapeLibrary,
			textureLibrary,
			shaderPairLibrary,
			modelLibrary);
	}
}